package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.CsPlatformType;
import com.ruoyi.common.utils.SnowflakeIdGenerator;
import com.ruoyi.system.client.SteamDTApiClientService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.CsBuyRecordMapper;
import com.ruoyi.system.mapper.CsInventoryMapper;
import com.ruoyi.system.service.ICsInventoryService;
import com.ruoyi.system.service.ICsOrnamentNameService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.ShiroUtils.getUserId;

/**
 * 库存物品Service业务层处理
 *
 * @author ruoyi
 * @date 2025-10-05
 */
@Service
public class CsInventoryServiceImpl extends ServiceImpl<CsInventoryMapper, CsInventory> implements ICsInventoryService {
    @Autowired
    private CsInventoryMapper csInventoryMapper;
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    @Autowired
    private CsBuyRecordMapper csBuyRecordMapper;
    @Autowired
    private ICsOrnamentNameService csOrnamentNameService;
    @Autowired
    private SteamDTApiClientService steamDTApiClientService;

    /**
     * 查询库存物品
     *
     * @param id 库存物品主键
     * @return 库存物品
     */
    @Override
    public CsInventory selectCsInventoryById(Long id) {
        return csInventoryMapper.selectCsInventoryById(id);
    }

    /**
     * 查询库存物品列表
     *
     * @param csInventory 库存物品
     * @return 库存物品
     */
    @Override
    public List<CsInventoryVo> selectCsInventoryList(CsInventory csInventory) {
        return csInventoryMapper.selectCsInventoryVoList(new QueryWrapper<CsInventory>().eq("user_id", getUserId()).eq(!ObjectUtils.isEmpty(csInventory.getAccount()), "account", csInventory.getAccount()).like(!ObjectUtils.isEmpty(csInventory.getName()), "name", csInventory.getName()));
    }

    @Override
    public CsInventoryTotalVo selectCsInventoryTotal(String name, Long account) {
        List<CsInventory> inventories = csInventoryMapper.selectList(new LambdaQueryWrapper<CsInventory>().eq(CsInventory::getUserId, getUserId()).eq(!ObjectUtils.isEmpty(account), CsInventory::getAccount, account).like(name != null, CsInventory::getName, name));
        CsInventoryTotalVo csInventoryTotalVo = new CsInventoryTotalVo();
        Long totalQuantity = 0L;
        Long totalAvailableQuantity = 0L;
        Long totalCost = 0L;
        Long totalInventoryPrice = 0L;
        Long totalHistoryProfit = 0L;
        Long totalUuProfit = 0L;
        Long totalC5Profit = 0L;
        Long totalBuffProfit = 0L;
        for (CsInventory inventory : inventories) {
            totalQuantity += inventory.getQuantity();
            totalAvailableQuantity += inventory.getAvailableQuantity();
            totalCost += inventory.getUnitCost() * inventory.getQuantity();
            totalHistoryProfit += inventory.getHistoryProfit();
            if (inventory.getUuPrice() != 0) {
                totalUuProfit += (inventory.getUuPrice() - inventory.getUnitCost()) * inventory.getQuantity();
            }
            if (inventory.getC5Price() != 0) {
                totalC5Profit += (inventory.getC5Price() - inventory.getUnitCost()) * inventory.getQuantity();
                totalInventoryPrice += inventory.getC5Price() * inventory.getQuantity();
            }
            if (inventory.getBuffPrice() != 0) {
                totalBuffProfit += (inventory.getBuffPrice() - inventory.getUnitCost()) * inventory.getQuantity();
            }
        }
        csInventoryTotalVo.setTotalQuantity(totalQuantity);
        csInventoryTotalVo.setTotalAvailableQuantity(totalAvailableQuantity);
        csInventoryTotalVo.setTotalCost(totalCost);
        csInventoryTotalVo.setTotalInventoryPrice(totalInventoryPrice);
        csInventoryTotalVo.setTotalHistoryProfit(totalHistoryProfit);
        csInventoryTotalVo.setTotalUuProfit(totalUuProfit);
        csInventoryTotalVo.setTotalC5Profit(totalC5Profit);
        csInventoryTotalVo.setTotalBuffProfit(totalBuffProfit);
        return csInventoryTotalVo;
    }

    /**
     * 新增库存物品
     *
     * @param csInventory 库存物品
     * @return 结果
     */
    @Override
    public int insertCsInventory(CsInventory csInventory) {
        csInventory.setUserId(getUserId());
        return csInventoryMapper.insert(csInventory);
    }

    /**
     * 修改库存物品
     *
     * @param csInventory 库存物品
     * @return 结果
     */
    @Override
    public int updateCsInventory(CsInventory csInventory) {
        if (csInventory.getMarketHashName() == null) {
            return 0;
        }
        CsOrnamentName csOrnamentName = csOrnamentNameService.selectCsOrnamentNameByMarketHashName(csInventory.getMarketHashName());
        csInventory.setName(csOrnamentName.getName());
        return csInventoryMapper.updateById(csInventory);
    }

    /**
     * 批量删除库存物品
     *
     * @param ids 需要删除的库存物品主键
     * @return 结果
     */
    @Override
    public int deleteCsInventoryByIds(String ids) {
        return csInventoryMapper.deleteCsInventoryByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除库存物品信息
     *
     * @param id 库存物品主键
     * @return 结果
     */
    @Override
    public int deleteCsInventoryById(Long id) {
        return csInventoryMapper.deleteCsInventoryById(id);
    }

    @Override
    public int upsetInventory(CsBuyRecord csBuyRecord) {
        CsInventory csInventory = csInventoryMapper.selectOne(new LambdaQueryWrapper<CsInventory>().eq(CsInventory::getMarketHashName, csBuyRecord.getMarketHashName()).eq(CsInventory::getUserId, csBuyRecord.getUserId()).eq(CsInventory::getAccount, csBuyRecord.getAccount()));
        if (csInventory == null) {
            // 新增数据
            csInventory = new CsInventory();
            csInventory.setId(snowflakeIdGenerator.nextId());
            csInventory.setUserId(getUserId());
            csInventory.setAccount(csBuyRecord.getAccount());
            csInventory.setName(csBuyRecord.getName());
            csInventory.setMarketHashName(csBuyRecord.getMarketHashName());
            csInventory.setQuantity(csBuyRecord.getQuantity());
            if (csBuyRecord.getPlatform().equals(String.valueOf(CsPlatformType.STEAM.val()))) {
                csInventory.setUnitCost((long) (csBuyRecord.getPrice() * 0.8));
            } else {
                csInventory.setUnitCost(csBuyRecord.getPrice());
            }
            csInventory.setAvailableQuantity(0L);
            csInventory.setBuffPrice(0L);
            csInventory.setC5Price(0L);
            csInventory.setSteamPrice(0L);
            csInventory.setUuPrice(0L);
            csInventory.setHistoryProfit(0L);
            csOrnamentNameService.updateCsOrnamentNameStatusByMarketHashName(csInventory.getMarketHashName(), 3L);
        } else {
            // 修改数据
            // 现有数量
            Long quantity = csInventory.getQuantity();
            csInventory.setQuantity(quantity + csBuyRecord.getQuantity());
            if (csInventory.getQuantity() <= 0) {
                csInventory.setUnitCost(0L);
            } else {
                // 本次新增的购买总价格
                Long unitCost = null;
                if (csBuyRecord.getPlatform().equals(String.valueOf(CsPlatformType.STEAM.val()))) {
                    unitCost = (long) (csBuyRecord.getPrice() * 0.8) * csBuyRecord.getQuantity();
                } else {
                    unitCost = csBuyRecord.getPrice() * csBuyRecord.getQuantity();
                }
                // 当前剩余的总价格
                Long totalCost = csInventory.getUnitCost() * quantity;
                csInventory.setUnitCost((unitCost + totalCost) / csInventory.getQuantity());
            }
        }
        return csInventoryMapper.upsetInventory(csInventory);
    }

    @Override
    public int updateInventoryByOldBuyRecord(CsBuyRecord newBuyRecord, CsBuyRecord oldCsBuyRecord) {
        // 获取当前库存信息
        CsInventory csInventory = csInventoryMapper.selectOne(new LambdaQueryWrapper<CsInventory>().eq(CsInventory::getMarketHashName, newBuyRecord.getMarketHashName()).eq(CsInventory::getUserId, getUserId()).eq(CsInventory::getAccount, newBuyRecord.getAccount()));
        // 先把旧的数据移除掉 在添加新的
        // 当前总数量
        Long totalQuantity = csInventory.getQuantity();
        // 当前总价
        Long totalPrice = csInventory.getUnitCost() * totalQuantity - oldCsBuyRecord.getPrice() * oldCsBuyRecord.getQuantity() + newBuyRecord.getQuantity() * newBuyRecord.getPrice();
        csInventory.setQuantity(totalQuantity - oldCsBuyRecord.getQuantity() + newBuyRecord.getQuantity());
        csInventory.setUnitCost(csInventory.getQuantity() == 0L ? 0L : totalPrice / csInventory.getQuantity());
        csInventory.setUpdateDate(null);
        return csInventoryMapper.updateById(csInventory);
    }

    @Override
    public void refreshAvailableQuantity() {
        // 刷新库存可用数量
        // 获取库存中到cd的列表
        List<CsBuyRecord> csBuyRecords = csBuyRecordMapper.selectList(new QueryWrapper<CsBuyRecord>().le("create_date", new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000)).eq("status", 0));
        if (csBuyRecords != null && !csBuyRecords.isEmpty()) {
            Map<String, Long> collect = csBuyRecords.stream().collect(Collectors.groupingBy(CsBuyRecord::getName, Collectors.summingLong(CsBuyRecord::getQuantity)));
            collect.forEach((name, quantity) -> {
                csInventoryMapper.update(null, Wrappers.<CsInventory>lambdaUpdate().eq(CsInventory::getName, name).setSql("available_quantity = available_quantity + " + quantity));
            });
            csBuyRecordMapper.update(null, new UpdateWrapper<CsBuyRecord>().set("status", 1).in("id", csBuyRecords.stream().map(CsBuyRecord::getId).collect(Collectors.toList())));
        }
    }

    @Override
    public List<CsInventory> getAvailableForSaleName(String name, Long account) {
        return csInventoryMapper.selectList(new LambdaQueryWrapper<CsInventory>().eq(CsInventory::getUserId, getUserId()).eq(!ObjectUtils.isEmpty(account), CsInventory::getAccount, account).gt(CsInventory::getAvailableQuantity, 0).like(CsInventory::getName, name));
    }

    @Override
    public int upsetInventoryByCsSalesRecord(CsSalesRecord csSalesRecord) {
        // 出售记录变更而修改库存信息

        return 0;
    }

    @Override
    public int updateInventoryByOldSalesRecord(CsSalesRecord newSalesRecord, CsSalesRecord oldSalesRecord) {
        CsInventory csInventory = csInventoryMapper.selectOne(new QueryWrapper<CsInventory>().eq("market_hash_name", newSalesRecord.getMarketHashName()));
        if (newSalesRecord.getQuantity() > oldSalesRecord.getQuantity() + csInventory.getAvailableQuantity()) {
            throw new RuntimeException("出售数量不能大于出售前数量");
        }
        // 更新前的价格

        // 更新库存剩余数量
        csInventory.setQuantity(csInventory.getQuantity() - oldSalesRecord.getQuantity() + newSalesRecord.getQuantity());
        csInventory.setAvailableQuantity(csInventory.getAvailableQuantity() - oldSalesRecord.getQuantity() + newSalesRecord.getQuantity());
        // 更新库存历史盈利
        csInventory.setHistoryProfit(csInventory.getHistoryProfit() - oldSalesRecord.getTotalProfit() + newSalesRecord.getTotalProfit());
        return csInventoryMapper.updateById(csInventory);
    }

    @Override
    @Transactional
    public int refreshPlatformPriceBySteamDT() {
        // 获取当前库存的数据
        List<CsInventory> inventories = csInventoryMapper.selectList(null);
        if (ObjectUtils.isEmpty(inventories)) {
            return 0;
        }
        Set<String> marketHashNames = inventories.stream().map(CsInventory::getMarketHashName).collect(Collectors.toSet());
        List<CsOrnamentName> csOrnamentNames = csOrnamentNameService.selectCsOrnamentNameList(new ArrayList<>(marketHashNames));
        if (ObjectUtils.isEmpty(csOrnamentNames)) {
            log.error("steamDT获取平台价格失败");
            return 0;
        }
        Map<String, CsOrnamentName> ornamentNameMap = csOrnamentNames.stream().collect(Collectors.toMap(CsOrnamentName::getMarketHashName, Function.identity()));
        for (CsInventory inventory : inventories) {
            CsOrnamentName csOrnamentName = ornamentNameMap.get(inventory.getMarketHashName());
            if (!ObjectUtils.isEmpty(csOrnamentName)) {
                inventory.setUpdateDate(csOrnamentName.getUpdateDate());
                if (!ObjectUtils.isEmpty(csOrnamentName.getSteamPrice())){
                    inventory.setSteamPrice(csOrnamentName.getSteamPrice());
                }
                inventory.setUuPrice(csOrnamentName.getYyypPrice());
                inventory.setC5Price(csOrnamentName.getC5Price());
                inventory.setBuffPrice(csOrnamentName.getBuffPrice());
            }
        }
        return csInventoryMapper.batchUpdatePlatformPrice(inventories);
    }

}
